package com.mxprojects.admin
{
	import com.mxprojects.gui.CategoryItem;
	import com.mxprojects.gui.ForumItem;
	import com.mxprojects.views.Admin;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class AdminEditForums extends Admin
	{
		private static const DRAG_BUFFER:int = 5;
		
		private static var topBounds:int;
		private static var bottomBounds:int;
		private static var categoryItem:CategoryItem; //use this to temp store categories for dragging

		
		public function AdminEditForums(){}
		
		public static function init():void {
			//allows for the up/down buttons
			for(var i:int = 0 ; i < MXP3.contentHolder.numChildren; i++){
				var child:DisplayObject = MXP3.contentHolder.getChildAt(i);
				if(child is CategoryItem){
					setupControls(child as CategoryItem);
				}
			}
		}
		
		private static function setupControls(category:CategoryItem):void {
			//setup the mouseover actions that will bring up the controls to change the position
			
//			var blocker:Sprite = new Sprite();
//			blocker.graphics.beginFill(0x000000, 0);
//			blocker.graphics.drawRect(0, 0, child.width, child.height);
//			blocker.graphics.endFill();
			
			//add the up/down button to the child so that we can override the regular mouse actions
			category.addEventListener(MouseEvent.ROLL_OVER, showControls, false, 0, true);
			category.addEventListener(MouseEvent.ROLL_OUT, hideControls, false, 0, true);
			
			for(var i:int = 0; i < category.numChildren; i++){
				if(category.getChildAt(i) is ForumItem){
					//setup the mouseovers
					var forum:ForumItem = category.getChildAt(i) as ForumItem;
					forum.addEventListener(MouseEvent.ROLL_OVER, showControls, false, 0, true);
					forum.addEventListener(MouseEvent.ROLL_OUT, hideControls, false, 0, true);
					
					//disable the hightlight
					forum.enableHighlights = false;
				}
			}
			
			//if(child is ForumItem){
				//ForumItem(child).enableHighlights = false;
			//}
			//child.addChildAt(blocker, child.numChildren);
		}
		
		private static function showControls(event:MouseEvent):void {
			trace("showing controls", event.currentTarget.numChildren);
			var display:DisplayObjectContainer = event.currentTarget as DisplayObjectContainer;
			for(var i:int = 0; i < display.numChildren; i++){
				trace(display.getChildAt(i).name);
			}
			
		}
		
		private static function hideControls(event:MouseEvent):void {
			trace("hiding controls");	
		}
		
		
		
		private static function setupDrag(category:CategoryItem):void {			
			//setup the dragging
			//_items.push(category);
			//_dictionary[category] = category;
			
			category.addEventListener(MouseEvent.MOUSE_DOWN, dragCategory, false, 0, true);
			category.addEventListener(MouseEvent.MOUSE_UP, stopDragCategory, false, 0, true);
			//category.addEventListener(MouseEvent.MOUSE_OUT, stopDragCategory, false, 0, true);
			
			//setup the forum dragging
			for(var i:int = 0; i < category.numChildren; i++){
				if(category.getChildAt(i) is ForumItem){
					//setup the drag
					var forum:ForumItem = category.getChildAt(i) as ForumItem;
					forum.addEventListener(MouseEvent.MOUSE_DOWN, dragForum, false, 0, true);
					forum.addEventListener(MouseEvent.MOUSE_UP, stopDragForum, false, 0, true);
					//forum.addEventListener(MouseEvent.MOUSE_OUT, stopDragForum, false, 0, true);
					
					//disable the hightlight
					forum.enableHighlights = false;
				}
			}
			
		}
		
		private static function dragCategory(event:MouseEvent):void {
			//allow the category to be dragged around
			/*
			_currentItem = event.currentTarget as CategoryItem;
			_currentItem.parent.setChildIndex(_currentItem, _currentItem.parent.numChildren - 1);
			_currentItem.startDrag(false, new Rectangle(0, topBounds, 0, bottomBounds - _currentItem.height));
			_currentItem.addEventListener(MouseEvent.MOUSE_MOVE, moveCategory, false, 0, true);
			
			_currentIndex = _items.indexOf(_currentItem);
			*/
			
			var category:CategoryItem = event.currentTarget as CategoryItem;
			category.parent.setChildIndex(category, category.parent.numChildren - 1);
			category.startDrag(false, new Rectangle(0, topBounds, 0, bottomBounds - category.height));
			category.addEventListener(MouseEvent.MOUSE_MOVE, moveCategory, false, 0, true);
		}
		
		private static function moveCategory(event:MouseEvent):void {
			//move categories out of the way if we need to
			//shuffleItems();
			
			var category:CategoryItem = event.currentTarget as CategoryItem;
			var catY:int = category.y;
			var catH:int = category.height;	
			
			event.updateAfterEvent();
			
			/*
			//figure out which categories are above and below
			for(var i:int = 0; i < MXP3.contentHolder.numChildren; i++){
				var child:DisplayObject = MXP3.contentHolder.getChildAt(i);
				if(child is CategoryItem && child != category){
					if(catY + catH <= child.y){
						//shift them down
						child.y += catH;
					}
				}
			}		
			*/
			
			//find out which category we are over
			var hitCategory:CategoryItem = categoryHitTest(category);
			if(hitCategory != null){
				var hitCatY:int = hitCategory.y;
				var hitCatH:int = hitCategory.height;
				
				//see if we need to shift it up or down
				if(catY + catH > hitCatY + hitCatH/2 + DRAG_BUFFER && catY < hitCatY + hitCatH/2){
					//shift the child up
					hitCategory.y -= catH - 1;
					return;
				}else if(catY - DRAG_BUFFER < hitCatY + hitCatH/2 && catY + catH > hitCatY + hitCatH/2 + DRAG_BUFFER){
					//shift it down
					hitCategory.y += catH - 1;
					return;
				}		
			}
			
		}
		/*
		private static function shuffleItems():void {
			var category:CategoryItem = _dictionary[_currentItem];
			var cell:Point = getCell();
			
			var col : int = cell.x;
			var row : int = cell.y;
			
			trace("col", col, "row", row);
			/*
			if(col == itemVO.col && row == itemVO.row)
			{
				return;
			}
			
		}
		*/
		
		private static function stopDragCategory(event:MouseEvent):void {
			//allow the category to be dragged around, but at the same time restricted
			var category:CategoryItem = event.currentTarget as CategoryItem;
			category.removeEventListener(MouseEvent.MOUSE_MOVE, moveCategory);
			category.stopDrag();
			
			var catY:int = category.y;
			var catH:int = category.height;
			
			//find out which category we are over
			var hitCategory:CategoryItem = categoryHitTest(category);
			if(hitCategory != null){
				var hitCatY:int = hitCategory.y;
				var hitCatH:int = hitCategory.height;
				
				//see if we need to snap it up or down
				if(catY <= hitCatY){
					//snap it up
					category.y -= catY + catH - hitCatY - 1;
					return;
				}else if(catY >= hitCatY + hitCatH/2){
					//snap it down
					category.y = hitCatY + hitCatH - 1;
					return;
				}
			}
		}
		
		private static function dragForum(event:MouseEvent):void {
			var forum:ForumItem = event.currentTarget as ForumItem;
			
			//if you click a forum it needs to break up from it's parent and be free to drag around whoring it up
			if(forum.parent != MXP3.contentHolder){
				//automatically move the forum to be realative to where it was
				var forumToGlobal:Point = forum.localToGlobal(new Point(0, 0));
				var forumToHolder:Point = MXP3.contentHolder.globalToLocal(forumToGlobal);
				forum.x = forumToHolder.x;
				forum.y = forumToHolder.y;
				
				//stop the category from being dragged as well
				if(forum.parent is CategoryItem){
					CategoryItem(forum.parent).removeEventListener(MouseEvent.MOUSE_DOWN, dragCategory);
					categoryItem = CategoryItem(forum.parent);
				}
				
				MXP3.addContent(forum);
			}
			
			//make sure this forum is on top
			forum.parent.setChildIndex(forum, forum.parent.numChildren-1);
			forum.startDrag(false, new Rectangle(0, topBounds + categoryItem.background.height - DRAG_BUFFER, 0, bottomBounds));
			forum.addEventListener(MouseEvent.MOUSE_MOVE, moveForum, false, 0, true);
			
		}
		
		private static function moveForum(event:MouseEvent):void {
			var forum:ForumItem = event.currentTarget as ForumItem;
			var forumY:int = forum.y;
			var forumH:int = forum.height;
			
			event.updateAfterEvent();
			
			//trace("FORUM Y", forumY);
			
			//find out which category we are over
			var category:CategoryItem = categoryHitTest(forum);
			if(category != null){
				var catH:int = category.background.height;
				
				//since when we click the forum it disconnects from the category parent we need to convert it to a local
				var forumLocal:Point = forum.globalToLocal(new Point(category.x, category.y));
				forumY = - (forumLocal.y + MXP3.contentHolder.y);
				
				//if we are hovering over a category slide it around
				if(forumY + forumH > catH/2 + DRAG_BUFFER && forumY < catH/2){
					category.y -= forumH - 1;
					
					//push the ones that are in the category already down
					moveCategoryChildren(category, forumH - 1);
					
					return;
				}else if(forumY - DRAG_BUFFER < catH/2 && forumY + forumH > catH/2 + DRAG_BUFFER){
					//shift it down
					category.y += forumH - 1;
					
					//push the ones that are in the category already up
					moveCategoryChildren(category, -(forumH - 1));
					
					return;
				}
				
				//now we gotta drill into the category item to move the forum items around
				var hitForum:ForumItem = forumHitTest(forum, category);
				if(hitForum != null){
					var hitForumY:int = hitForum.y;
					var hitForumH:int = hitForum.height;
					
					//see if we need to shift it up or down
					if(forumY + forumH > hitForumY + hitForumH/2 + DRAG_BUFFER && forumY < hitForumY + hitForumH/2){
						//shift the child up
						hitForum.y -= forumH - 1;
						return;
					}else if(forumY - DRAG_BUFFER < hitForumY + hitForumH/2 && forumY + forumH > hitForumY + hitForumH/2 + DRAG_BUFFER){
						//shift it down
						hitForum.y += forumH - 1;
						return;
					}
				}
			}
		}
		
		private static function stopDragForum(event:MouseEvent):void {
			//restore the mouse down action to the category
			if(categoryItem != null){
				if(!categoryItem.hasEventListener(MouseEvent.MOUSE_DOWN)){
					categoryItem.addEventListener(MouseEvent.MOUSE_DOWN, dragCategory, false, 0, true);
				}
			}
			
			//stop dragging and snap into place
			var forum:ForumItem = event.currentTarget as ForumItem;
			forum.removeEventListener(MouseEvent.MOUSE_MOVE, moveForum);
			forum.stopDrag();
			
			var forumY:int = forum.y;
			var forumH:int = forum.height;
			
			var category:CategoryItem = categoryHitTest(forum);
			if(category != null){
				var catY:int = category.y;
				var catH:int = category.background.height;
				
				trace("landed on", category.title.text, forumY, catY, catH);
				
				//see if we need to snap it up or down
				if(forumY <= catY){
					//snap it up
					forum.y -= forumY + forumH - catY - 1;
					
					//figure out what the category above the one we landed on first was
					var hitCategory:CategoryItem = categoryHitTest(forum);
					trace("now it's on", hitCategory.title.text);
					
					var forumLocal:Point = forum.globalToLocal(new Point(hitCategory.x, hitCategory.y));
					trace(- (forumLocal.y + MXP3.contentHolder.y));
					hitCategory.addChild(forum);
					forum.y = - (forumLocal.y + MXP3.contentHolder.y);
					return;
					
				}else if(forumY >= catY + catH/2){
					//snap it down							
					category.addChild(forum);
					forum.y = catH - 1;
					trace("snapped down");
					return;
				}
			}
		}
		
		private static function categoryHitTest(objectToHitTest:DisplayObject):CategoryItem {
			for(var i:int = 0; i < MXP3.contentHolder.numChildren; i++){
				var child:DisplayObject = MXP3.contentHolder.getChildAt(i);
				if(child is CategoryItem && child != objectToHitTest){
					if(objectToHitTest.hitTestObject(child)){
						//if we've hit another category, let's see how much we are into it
						return child as CategoryItem;
					}
				}
			}
			
			//if we didn't find anything report null
			return null;
		}
		
		private static function forumHitTest(forum:ForumItem, category:CategoryItem):ForumItem {
			for(var i:int = 0; i < category.numChildren; i++){
				var catChild:DisplayObject = category.getChildAt(i);
				if(catChild is ForumItem){
					if(forum.hitTestObject(catChild)){
						return catChild as ForumItem;
					}
				}
			}
			
			//return null if we didn't find anything
			return null;
		}
		
		private static function moveCategoryChildren(category:CategoryItem, movementAmount:int):void {
			for(var i:int = 0; i < category.numChildren; i++){
				var moveChild:DisplayObject = category.getChildAt(i);
				if(moveChild is ForumItem){
					moveChild.y += movementAmount;
				}
			}
		}
		/*
		private static function getCell():Point {
			var cell:Point = new Point();
			var x:int = _currentItem.x;
			var y:int = _currentItem.y;
			
			//find the 
			
			cell.x = Math.max(0, Math.min(_cols - 1, Math.round(x / (MXP3.wStage + _padd))));
			cell.y = Math.max(0, Math.min(_rows - 1, Math.round(y / (_currentItem.height + _padd))));
			
			return cell;
		}
		*/
	}
}